package com.ccys.common.util;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
 */
public class StringUtil extends StringUtils {

    private static final char SEPARATOR = '_';
    private static final String CHARSET_NAME = "UTF-8";


    public static void main(String[] args) {
        System.out.println(abbrString("11", 5));
    }

    private StringUtil() {

    }

    /**
     * 判断字符串是否只含有数字或字符
     *
     * @param input
     * @return
     */
    public static boolean isNumAndStr(String input) {
        if (input != null) {
            return input.matches("[0-9A-Za-z_]*");
        }
        return false;
    }

    /**
     * 判断字符串是否只含有数字
     *
     * @param input
     * @return
     */
    public static boolean isNum(String input) {
        if (input != null) {
            return input.matches("[0-9]*");
        }
        return false;
    }

    /**
     * 判断字符串是否整数
     *
     * @param input
     * @return
     */
    public static boolean isInt(String input) {
        if (input != null) {
            return input.matches("^[+-]?[\\d]+$");
        }
        return false;
    }

    /**
     * 判断字符串是否小数
     *
     * @param input
     * @return
     */
    public static boolean isFloat(String input) {
        if (input != null) {
            return input.matches("^[+-]?[\\d]+\\.[\\d]+$");
        }
        return false;
    }

    /**
     * 转换为Boolean类型 'true', 'on', 'y', 't', 'yes' or '1' (case insensitive) will
     * return true. Otherwise, false is returned.
     */
    @NotNull
    public static Boolean toBoolean(final Object val) {
        if (val == null) {
            return false;
        }
        return BooleanUtils.toBoolean(val.toString()) || "1".equals(val.toString());
    }

    /**
     * 如果对象为空，则使用defaultVal值 see: ObjectUtils.toString(obj, defaultVal)
     *
     * @param obj
     * @param defaultVal
     * @return
     */
    public static String toString(final Object obj, final String defaultVal) {
        return obj == null ? defaultVal : obj.toString();
    }

    /**
     * 是否包含字符串
     *
     * @param str  验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inString(String str, String... strs) {
        if (str != null) {
            for (String s : strs) {
                if (str.equals(trim(s))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 替换掉HTML标签方法
     */
    public static String replaceHtml(String html) {
        if (isBlank(html)) {
            return "";
        }
        String regEx = "<.+?>";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(html);
        String s = m.replaceAll("");
        return s;
    }

    /**
     * 替换为手机识别的HTML，去掉样式及属性，保留回车。
     *
     * @param html
     * @return
     */
    @NotNull
    @Contract(pure = true)
    public static String replaceMobileHtml(String html) {
        if (html == null) {
            return "";
        }
        return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
    }

    /**
     * 缩略字符串
     *
     * @param str    目标字符串
     * @param length 截取长度
     * @return
     */
    @NotNull
    public static String abbrString(String str, int length) {
        if (StringUtil.isBlank(str)) {
            return "";
        }
        if (str.length() > length) {
            str = str.substring(0, length) + "...";
        }
        return str;
    }


    /**
     * 转换为Double类型
     *
     * @param val
     * @return
     */
    @NotNull
    public static Double toDouble(Object val) {
        if (val == null) {
            return 0D;
        }
        try {
            return Double.valueOf(trim(val.toString()));
        } catch (Exception e) {
            return 0D;
        }
    }

    /**
     * 转换为Float类型
     *
     * @param val
     * @return
     */
    @NotNull
    public static Float toFloat(Object val) {
        return toDouble(val).floatValue();
    }

    /**
     * 转换为Long类型
     *
     * @param val
     * @return
     */
    @NotNull
    public static Long toLong(Object val) {
        return toDouble(val).longValue();
    }

    /**
     * 转换为Integer类型
     *
     * @param val
     * @return
     */
    @NotNull
    public static Integer toInteger(Object val) {
        return toLong(val).intValue();
    }


    /**
     * 驼峰命名法工具
     * <p>
     * toCamelCase(" hello_world ") == "helloWorld"
     *
     * @param s
     * @return
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 驼峰命名法工具
     * <p>
     * toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *
     * @param s
     * @return
     */
    public static String toCapitalizeCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = toCamelCase(s);
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    /**
     * 驼峰命名法工具
     * <p>
     * toUnderScoreCase("helloWorld") = "hello_world"
     *
     * @param s
     * @return
     */
    public static String toUnderScoreCase(String s) {
        if (s == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            boolean nextUpperCase = true;
            if (i < (s.length() - 1)) {
                nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
            }
            if ((i > 0) && Character.isUpperCase(c)) {
                if (!upperCase || !nextUpperCase) {
                    sb.append(SEPARATOR);
                }
                upperCase = true;
            } else {
                upperCase = false;
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 转换为JS获取对象值，生成三目运算返回结果
     *
     * @param objectString 对象串 例如：row.user.id
     * @return 返回：!row?'':!row.user?'':!row.user.id?'':row.user.id
     */
    @NotNull
    public static String jsGetVal(String objectString) {
        StringBuilder result = new StringBuilder();
        StringBuilder val = new StringBuilder();
        String[] vals = split(objectString, ".");
        for (int i = 0; i < vals.length; i++) {
            val.append("." + vals[i]);
            result.append("!" + (val.substring(1)) + "?'':");
        }
        result.append(val.substring(1));
        return result.toString();
    }


    /**
     * 将字符串中省，市，区，县以,号分割
     *
     * @param addr 四川省成都市武侯区仪陇县
     * @return 四川省, 成都市, 武侯区, 仪陇县
     */
    public static String[] getFormatAddr(@NotNull String addr) {
        int indexOfProvince = addr.indexOf("省");
        int indexOfCity = addr.indexOf("市");
        int indexOfDistrict = addr.indexOf("区");
        int indexOfCounty = addr.indexOf("县");
        String province = "";
        if (indexOfProvince != -1) {
            province = addr.substring(0, indexOfProvince + 1);
        }
        String city = "";
        if (indexOfCity != -1) {
            city = addr.substring(indexOfProvince + 1, indexOfCity + 1);
        }
        String district = "";
        if (indexOfDistrict != -1) {
            district = addr.substring(indexOfCity + 1, indexOfDistrict + 1);
        }
        String county = "";
        if (indexOfCounty != -1) {
            county = addr.substring(indexOfDistrict + 1, indexOfCounty + 1);
        }
        String[] addrs = {province, city, district, county};
        return addrs;
    }

    /**
     * 判断字符串的编码类型
     *
     * @param str
     * @return
     */
    public static String getEncoding(String str) {
        String encode = "GB2312";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
        } catch (Exception e) {
        }
        encode = "ISO-8859-1";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
        } catch (Exception e) {
        }
        encode = "UTF-8";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
        } catch (Exception e) {
        }
        encode = "GBK";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
        } catch (Exception e) {
        }
        return "未知";
    }

    /**
     * 字符串编码转换
     *
     * @param encode
     * @param par
     * @return
     */
    public static String encoding(String encode, String par) {
        try {
            par = new String(par.getBytes(StringUtil.getEncoding(par)), encode);
        } catch (Exception e) {
            return par;
        }
        return par;
    }


}
